package it.aekidna.xmlmapping
{
   import flash.utils.Dictionary;
   import flash.utils.flash_proxy;
   
   import mx.utils.ObjectProxy;
   
   use namespace flash_proxy;
   public dynamic class XmlMappingContext  extends ObjectProxy
   {

      XMLMAPPING_PRIVATE var mappedProperties : Dictionary = new Dictionary( true );
      XMLMAPPING_PRIVATE var mappingsStack : Array = [];  
      
      XMLMAPPING_PRIVATE function init( mapping : XmlMapping ) : void
      {
         XMLMAPPING_PRIVATE::mappingsStack.unshift( new MappingInfo() );
      }

      XMLMAPPING_PRIVATE function cleanUp() : void
      {
         var mappingInfo : MappingInfo = MappingInfo( XMLMAPPING_PRIVATE::mappingsStack.shift() );
         //var currentMappingProperties : Array = XMLMAPPING_PRIVATE::mappingsStack.shift();
         while( mappingInfo.properties.length > 0 )
         {
            delete XMLMAPPING_PRIVATE::mappedProperties[ 
               mappingInfo.properties.pop()
               ]; 
         }
      }
      
      XMLMAPPING_PRIVATE function propertyMapped( property : MapProperty, value : * ) : void
      {
         MappingInfo(XMLMAPPING_PRIVATE::mappingsStack[0] ).properties.push( property );
         XMLMAPPING_PRIVATE::mappedProperties[ property ] = value;
      } 
      
      XMLMAPPING_PRIVATE function setVariable( name : String, value : * ) : void
      {
         MappingInfo(XMLMAPPING_PRIVATE::mappingsStack[0] ).variables[ name ] = value;
      } 
      
      /**
      * Gives access an already-parsed property's value.
      * Useful to perform cross-property contitional mapping.
      */
      public function getPropertyValue( property : MapProperty ) : *
      {
         if( XMLMAPPING_PRIVATE::mappedProperties[ property ] == null )
         {
            //TODO: wrap this nicely in XmlMapping errors handling
            throw new Error("attempt to access an unmapped property: early referencing?");
         }
         return XMLMAPPING_PRIVATE::mappedProperties[ property ];
      }

      flash_proxy override function getProperty( name : *) : *
      {
         if( String( name ).match(/^\$\w+/) )
         {
            var mappingInfo : MappingInfo = MappingInfo( XMLMAPPING_PRIVATE::mappingsStack[ 0 ] );
            if( mappingInfo.variables.hasOwnProperty( String( name ).substr( 1 ) ) )
            {
               return mappingInfo.variables[ String( name ).substr( 1 ) ];
            }
         }
         return null;
      }
   }
}
import flash.utils.Dictionary;
   
class MappingInfo 
{
  public var variables : Dictionary = new Dictionary();
  public var properties : Array = [];
}
